// =================================================================
// File: unlink.cpp
// Desc: Contains function to unlink linked files and remove files
// =================================================================


// =================================================================
// INCLUDES
// =================================================================

#include <string>
#include "FSManager.h"
#include "commands.h"
#include "File.h"
#include "Directory.h"
#include "Inode.h"
#include "IndirectBlock.h"
#include "config.h"

using namespace std;
// =================================================================
// FUNCTIONS
// =================================================================

// =================================================================
// Name: unlink
// Desc: Unlinks the given file, and removes files if link count is 0
// Args: string path - The path for the file to be unlinked
//       FSManager* fsm - pointer to active FSManager object
// =================================================================

void unlink(string path, FSManager *fsm){

  int inode_index;
  Inode *node;
  Directory *parent_dir;

  size_t found = path.find_last_of("/");
  if (found == string::npos) {
    parent_dir = fsm->GetCurrentDirectory();
  } else {
    parent_dir = fsm->ReadDirectory(path.substr(0, found));
  }

  string filename = path.substr(found+1);
  // cout << "Filename: " << filename << endl;
  inode_index = parent_dir->GetEntry(filename);

  node = fsm->ReadInode(inode_index);

  node->SetNumLinks(node->GetNumLinks()-1);
  if (node->GetNumLinks() <= 0)
    delete_blocks(node,fsm);

  parent_dir->RemoveEntry(filename);
  // cout << parent_dir->GetEntries().size() << endl;
  fsm->WriteDirectory(parent_dir);

  // Update in-memory current and root directory structures
  if(parent_dir->GetInodeIndex() == fsm->GetRootDirectory()->GetInodeIndex()){
   // Directory *root_dir = fsm->GetRootDirectory();
    //delete root_dir;

    // Update current if current and root directory are equal
    if (fsm->GetRootDirectory() == fsm->GetCurrentDirectory())
      fsm->SetCurrentDirectory(parent_dir);
    fsm->SetRootDirectory(parent_dir);
  }
  else if(parent_dir->GetInodeIndex() == fsm->GetCurrentDirectory()->GetInodeIndex()){
    Directory *current_dir = fsm->GetCurrentDirectory();
    if (parent_dir != current_dir)
      delete current_dir;
    fsm->SetCurrentDirectory(parent_dir);
  }

  // If parent is neither root or current, safe to delete
  else
  {
    delete parent_dir;
  }

  if(node->GetNumLinks() == 0){
    fsm->GetSB()->AddFreeInode(inode_index);
    delete node;
  }

  cout << path << " successfully unlinked" << endl;
}
